/*
 * Copyright 2009 Douglas Lockamy, dlockamy_at_gmail.com
 * All rights reserved. Distributed under the terms of the MIT License.
 */
/*
    vfs spec
    
    FS File Types:
    1 Directory
    2 Text File
    3 Binary File
    4 Symlink
    5 Mount Point
    6 Union Link

    FS File Read Flags
    1 Request Type
    2 Return Array of File in Directory
    3 Read text/data file

*/

if (!this.procfs) procfs = {};
proc_vfsNode.item=procfs;
procfs.version = '0.1';

procfs.init = function()
{
    procRoot = new fileNode();
    procRoot.Name="/";
    procRoot.Type = 1;
    procRoot.prev = 0;
    procRoot.next = 0;
    procRoot.Data = new Array();
    procRoot.Parent = 0;
    
    procRoot.Data[0] = new fileNode();
    
    var ctl = procRoot.Data[0];
    ctl.Name="bash";
    ctl.Type=2;
    ctl.prev=0;
    ctl.next=0;
    ctl.Data="a bunch of text";
    
    
    
};

procfs.mount = function(serverAddress,fs_type,mountPoint,user,pass,argv)
{
/*
    var mPath = benix.fsBuildMountPath(rootfs,mountPoint);
    var name = mountPoint.split("/");
    var aNode = vfs.walk(mPath);
    var counter = 0;

    while(vfsList[counter].Name != fs_type && counter < vfsList.length-1)
    {  
        counter++;
    }
    if(aNode.Type == 1 && vfsList[counter].Name == fs_type)
    {
        aNode.Data[aNode.Data.length] =  new fileNode(); 

        var mounter = aNode.Data[aNode.Data.length - 1 ];
        
        aNode.Data[aNode.Data.length-1].Next = mounter;
        
        mounter.Name=name[name.length-1];
        mounter.Type = 5;
        mounter.Data= new mountNode();
        mounter.Data[0]=fs_type;
        mounter.Data[1]=serverAddress;
        mounter.Data[2]=0;
        mounter.Data[3]=vfsList[counter].item;
        mounter.Parent = aNode;

        if(aNode.Data.length < 1)
            mounter.prev=0;
        else
            mounter.prev=aNode.Data[aNode.Data.length-2];
        mounter.next=0;

        vfsList[counter].item.init();

        return 0;
    }
    else*/
        return -1;
};

procfs.umount = function(mountPoint)
{
    var aNode = vfs.walk(mountPoint);
    if(aNode.Type == 5)
    {
        if(!aNode.Data[3].umount() )
        {
            vfs.write(mountPoint,0,null);
        }
        return 0;
    }
    else  
        benix.stdout('<br>Not a mount point<br>');
};

procfs.read = function(path,flags,buffer,offset,length,sessionKey)
{
//alert('procfs.read()' + ' ' + flags + path);
    if(flags =='1')
    {
        var readNode = benix.fsWalk(procRoot,path);

        if(readNode.Type == 1)
            return 1;
        if(readNode.Type==5)
        {
            readNode.Data[3].read(path,1);
            return 1;
        }           
        else
            return 0;
    }
    if(flags =='2')
    {    
        var readNode = benix.fsWalk(procRoot,path);

        if(readNode.Type == 1)
            return readNode;
        if(readNode.Type==5)
        {
            var loadPath = benix.fsBuildMountPath(aNode,path);
        
            return(readNode.Data[3].read(loadPath,flags) );
        }           
        else
            return readNode;
    }
    if(flags =='3')
    {  
        var readNode = benix.walk(procRoot,path);
        
        if(readNode.Type == 1)
        {
            if(readNode.Data[0].Name)
            return readNode.Data[0].Name;
            else
            return "File Read Error"
        }
        if(readNode.Type==5)
        {
            var loadPath = benix.fsBuildMountPath(aNode,path);
        
            return(readNode.Data[3].read(loadPath,flags) );
        }           
        else
            return readNode.Data;    
    }
    else
        return -1;
};

procfs.write = function(path,flags,buffer,offset,length,sessionKey)
{

    var workPath = '/';
    var aNode = 0;
    var pathArray = path.split('/');
    var counter=0;
    
    while(counter <= pathArray.length-2)
    {
        if(workPath == '/')
            workPath = workPath + pathArray[counter];
        else
            workPath = workPath + '/' + pathArray[counter];
        counter++;
    }

    if(flags==0)
    {
        //unlink a node
            counter = 0;
            aNode = benix.fsWalk(procRoot,path);
            
            if(aNode.Type == 5)
            {
                var loadPath = benix.fsBuildMountPath(aNode,path);

                return(aNode.Data[3].write(loadPath,flags,buffer) );
            };
            
            var prevNode = aNode.prev;   
            var nextNode = aNode.next;      

            while(aNode.Parent.Data[counter].Name != aNode.Name && counter < aNode.Parent.Data.length)
            {
                counter++;
            }
            
            aNode.Parent.Data.splice(counter,1);
            
            prevNode.next = nextNode;
            nextNode.prev = prevNode;
    }
    
    if(flags==1)
    {
        aNode = benix.fsWalk(procRoot,workPath);

        if(aNode.Type == 1 && buffer == 1)
        {
            aNode.Data[aNode.Data.length] = new fileNode;
            var newDir = aNode.Data[aNode.Data.length-1];
            newDir.Name = pathArray[pathArray.length-1];
            newDir.Type = 1;
            newDir.next = 0;
            newDir.Data = new Array();
            newDir.prev = aNode.Data[aNode.Data.length-1];
            newDir.Parent = aNode;

            if(aNode.Data.length >= 2 )
            {        
                aNode.Data[aNode.Data.length-2].next=newDir;
            }          
        }
        
        if(aNode.Type==5 )
        {
            var loadPath = benix.fsBuildMountPath(aNode,path);

            return(aNode.Data[3].write(loadPath,flags,buffer) );
        }  
        
        else
            return -1;
    }
    else if(flags==2)
    {
        aNode = benix.walk(procRoot,workPath);

        if(aNode.Type==1 )
        {
            var newfile = aNode.Data[aNode.Data.length] = new fileNode();
            newfile.Name = pathArray[pathArray.length-1];
            newfile.Type = 2;
            newfile.next = 0;
            newfile.Data = buffer;
            newfile.prev = aNode.Data[aNode.Data.length-1];
            
            if(aNode.Data.length >= 2 )
            {        
                aNode.Data[aNode.Data.length-2].next=newfile;
            }           
        }
        
        if(aNode.Type==5 )
        {
            var loadPath = benix.fsBuildMountPath(aNode,path);

            return(aNode.Data[3].write(loadPath,flags,buffer) );
        }  
        
        else
            return -1;
    }
    else if(flags==3)
    {
        alert('link unsupported at this time');
    }
    else 
        return -1;

};
